﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

/*
   Copyright 2011 lotrodps@gmail.com

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/
namespace LOTRO_DPS_Parser
{
    public partial class MainApp : Form
    {
        public MainApp()
        {
            InitializeComponent();
        }

        // Initilize some variables and lists for later
        List<string> lines = new List<string>();
        List<string> names = new List<string>();
        List<string> words = new List<string>();

        public string filename;

        
     
        bool bInter;
        bool bDefeated;
        bool bBlow;
        bool bHeader;
        bool bLeft;
        bool bJoin;
        bool bYou;
        bool bYour;
        bool bSuccumbed;
        bool bLoot;
        bool bLoot2;
        bool bCure;
        bool bChat;

        private void openButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog chooseFile = new OpenFileDialog();
            string userProfile = Environment.GetEnvironmentVariable("userprofile");
            string filePath = userProfile + "\\My Documents\\The Lord of the Rings Online\\";
            chooseFile.InitialDirectory = filePath;

            if (chooseFile.ShowDialog() == DialogResult.OK)
            {

                // Clear out this list before populating it
                lines.Clear();

                // Reset the default selection to empty
                comboBox1.SelectedIndex = -1;
                comboBox2.SelectedIndex = -1;

                // Clear out the combo boxes
                comboBox1.Items.Clear();
                comboBox2.Items.Clear();

                textBox1.Text = chooseFile.FileName.ToString();
                filename = chooseFile.FileName.ToString();

                using (StreamReader l = new StreamReader(filename))
                {
                    string line;
                    while ((line = l.ReadLine()) != null)
                    {
                        lines.Add(line);
                    }
                }

                // Clear out these two lists before populating them
                names.Clear();
                words.Clear();

                foreach (string s in lines)
                {

                    // Determine some basic facts about each line in the combat log
                    bInter = s.Contains(" interrupted ");
                    bDefeated = s.Contains(" defeated ");
                    bSuccumbed = s.Contains(" succumbed ");
                    bHeader = s.StartsWith("#");
                    bLeft = s.StartsWith("Left ");
                    bJoin = s.StartsWith("Joined ");
                    bYou = s.StartsWith("You ");
                    bYour = s.StartsWith("Your ");
                    bBlow = s.StartsWith("blow ");
                    bLoot = s.Contains(" contents ");
                    bLoot2 = s.Contains(" acquired ");
                    bCure = s.Contains(" cure");
                    bChat = s.StartsWith("[");


                    bool bIgnore;

                    // If any of these conditions are met, the line should not be used to detect the character names involved in the combat log
                    if (bLeft == true || bJoin == true || bDefeated == true || bInter == true || 
                        bHeader == true || bBlow == true || bYou == true || bSuccumbed == true || 
                        bLoot == true || bLoot2 == true || bYour == true || bCure == true || bChat == true)
                    {
                        bIgnore = true;
                    }
                    else
                    {
                        bIgnore = false;
                    }


                    // Parse out the character names and add them to an array
                    if (bIgnore == false)
                    {

                        string name;
                        words = s.Split(' ').ToList();
                        //string[] words = s.Split(' ');
                        var firstWord = words.First();
                        string strWord = firstWord.ToString();
                        name = firstWord.ToString();

                        bool exists = names.Contains(name);
                        if (exists == false)
                        {
                            names.Add(name);
                        }
                    }
                }

                // Populate the drop-down boxes with the charater names found in the combat log
                //string[] arrNames;
                //arrNames = names.ToArray();

                comboBox2.Items.Add("All");

                names.Sort();

                foreach (string n in names)
                {
                    comboBox1.BeginUpdate();
                    comboBox1.Items.Add(n);
                    comboBox1.EndUpdate();
                    comboBox2.BeginUpdate();
                    comboBox2.Items.Add(n);
                    comboBox2.EndUpdate();
                }


                /*
                comboBox1.BeginUpdate();
                comboBox1.Items.AddRange(names.ToArray());
                comboBox1.EndUpdate();
                 */

                comboBox1.Enabled = true;

                /*
                comboBox2.BeginUpdate();
                comboBox2.Items.Add("All");
                comboBox2.Items.AddRange(names.ToArray());
                comboBox2.EndUpdate();
                */

                comboBox2.Enabled = true;

                parseCombat.Enabled = true;

                label1.Enabled = true;
                label2.Enabled = true;

            }
        }


        private void parseCombat_Click(object sender, EventArgs e)
        {
            // Figure out who's who
            string myChar = comboBox1.SelectedItem.ToString();
            string myOpponent = comboBox2.SelectedItem.ToString();

            ParseCombatLog parseCombat = new ParseCombatLog();

            // Get all the outgoing events and attacks
            int myDPS = parseCombat.ParseDPS(myChar, myOpponent, lines);
            int myEvades = parseCombat.ParseEvades(myOpponent, myChar, lines);
            int myBlocks = parseCombat.ParseBlocks(myOpponent, myChar, lines);
            int myParries = parseCombat.ParseParries(myOpponent, myChar, lines);
            int myResists = parseCombat.ParseResists(myOpponent, myChar, lines);
            int myAttacks = parseCombat.NumberOfAttacks(myChar, myOpponent, lines);
            int myPartialAttacks = parseCombat.PartialAttacks(myChar, lines);
            string[] bigHitOut = parseCombat.FindBiggestHit(myChar, myOpponent, lines);
            int myCrits = parseCombat.FindCrits(myChar, myOpponent, lines);
            int myDevCrits = parseCombat.FindDevCrits(myChar, myOpponent, lines);
            int[] myPoints = parseCombat.GetPoints(lines);

            // Get all the incoming events and attacks
            int theirDPS = parseCombat.ParseDPS(myOpponent, myChar, lines);
            int theirEvades = parseCombat.ParseEvades(myChar, myOpponent, lines);
            int theirBlocks = parseCombat.ParseBlocks(myChar, myOpponent, lines);
            int theirParries = parseCombat.ParseParries(myChar, myOpponent, lines);
            int theirResists = parseCombat.ParseResists(myChar, myOpponent, lines);
            int theirAttacks = parseCombat.NumberOfAttacks(myOpponent, myChar, lines);
            int theirPartialAttacks = parseCombat.PartialAttacks(myOpponent, lines);
            string[] bigHitIn = parseCombat.FindBiggestHit(myOpponent, myChar, lines);
            int theirCrits = parseCombat.FindCrits(myOpponent, myChar, lines);
            int theirDevCrits = parseCombat.FindDevCrits(myOpponent, myChar, lines);

            int myTotalAvoidances = myEvades + myBlocks + myParries;
            int theirTotalAvoidances = theirEvades + theirBlocks + theirParries;
            int mySuccessfulAttacks = myAttacks - theirEvades - theirBlocks - theirParries - theirResists;
            int theirSuccessfulAttacks = theirAttacks - myEvades - myBlocks - myParries - myResists;


            decimal myDPA;
            decimal myDPATaken;
            decimal theirAvoidResist;
            decimal myAvoidResist;
            decimal myCritPct;
            decimal theirCritPct;
            decimal myDevCritPct;
            decimal theirDevCritPct;
            decimal myPPK;

            #region Avoid_Divide_By_Zero
            // These conditionals avoid potential divide-by-zero exceptions
            if (myAttacks > 0 && myDPS > 0)
            {
                myDPA = parseCombat.DamagePerAttack(myAttacks, myDPS);
            }
            else
            {
                myDPA = 0;
            }

            if (theirAttacks > 0 && theirDPS > 0)
            {
                myDPATaken = parseCombat.DamagePerAttack(theirAttacks, theirDPS);
            }
            else
            {
                myDPATaken = 0;
            }


            if (mySuccessfulAttacks > 0)
            {
                theirAvoidResist = 100 - parseCombat.CalculatePercentage(myAttacks, mySuccessfulAttacks);
            }
            else
            {
                theirAvoidResist = 0;
            }

            if (theirSuccessfulAttacks > 0)
            {
                myAvoidResist = 100 - parseCombat.CalculatePercentage(theirAttacks, theirSuccessfulAttacks);
            }
            else
            {
                myAvoidResist = 0;
            }

            if (mySuccessfulAttacks > 0 && myAttacks > 0)
            {
                myCritPct = parseCombat.CalculatePercentage(mySuccessfulAttacks, myCrits);
            }
            else
            {
                myCritPct = 0;
            }

            if (theirSuccessfulAttacks > 0 && theirAttacks > 0)
            {
                theirCritPct = parseCombat.CalculatePercentage(theirSuccessfulAttacks, theirCrits);
            }
            else
            {
                theirCritPct = 0;
            }

            if (mySuccessfulAttacks > 0 && myAttacks > 0)
            {
                myDevCritPct = parseCombat.CalculatePercentage(mySuccessfulAttacks, myDevCrits);
            }
            else
            {
                myDevCritPct = 0;
            }

            if (theirSuccessfulAttacks > 0 && theirAttacks > 0)
            {
                theirDevCritPct = parseCombat.CalculatePercentage(theirSuccessfulAttacks, theirDevCrits);
            }
            else
            {
                theirDevCritPct = 0;
            }

            if (myPoints[0] > 0 && myPoints[1] > 0)
            {
                myPPK = parseCombat.CalculatePPK(myPoints[0], myPoints[1]);
            }
            else
            {
                myPPK = 0;
            }
            #endregion

            string myBiggestHitOut = bigHitOut[0];
            string myBiggestHitIn = bigHitIn[0];
            string bigCombatLogOut = bigHitOut[1];
            string bigCombatLogIn = bigHitIn[1];

            int myKBs = parseCombat.MyKillingBlows(lines);

            List<string> myKills = parseCombat.WhoDied(lines);



            TextResults resultsDialog = new TextResults();

            // Pass all the stats to the public interfaces for the results form, and launch the form

            if (comboBox2.Text == "All")
            {
                resultsDialog.IncludeKBs = true;
            }
            else
            {
                resultsDialog.IncludeKBs = false;
            }

            resultsDialog.MyDPS = myDPS;
            resultsDialog.TheirDPS = theirDPS;
            resultsDialog.MyDPA = myDPA;
            resultsDialog.TheirDPA = myDPATaken;
            resultsDialog.BiggestHitOut = myBiggestHitOut;
            resultsDialog.BiggestHitIn = myBiggestHitIn;
            resultsDialog.BigHitTextIn = bigCombatLogIn;
            resultsDialog.BigHitTextOut = bigCombatLogOut;
            resultsDialog.MySuccessfulAttacks = mySuccessfulAttacks;
            resultsDialog.TheirSuccessfulAttacks = theirSuccessfulAttacks;
            resultsDialog.MyAttacks = myAttacks;
            resultsDialog.TheirAttacks = theirAttacks;
            resultsDialog.TheirAvoidResist = theirAvoidResist;
            resultsDialog.MyAvoidResist = myAvoidResist;
            resultsDialog.MyName = myChar;
            resultsDialog.OpponentName = myOpponent;
            resultsDialog.MyKBs = myKBs;
            resultsDialog.MyKills = myKills;
            resultsDialog.MyCritPct = myCritPct;
            resultsDialog.TheirCritPct = theirCritPct;
            resultsDialog.MyDevCritPct = myDevCritPct;
            resultsDialog.TheirDevCritPct = theirDevCritPct;
            resultsDialog.PPK = myPPK;
            resultsDialog.Points = myPoints[0];
            resultsDialog.ShowDialog();

        }
    }
}
